/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tetris.model.blokken;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import javax.swing.Timer;

/**
 *
 * @author batist
 */
public class Bord extends Observable implements ActionListener {

    private AbstractBlok huidigBlok;
    private AbstractBlok volgendBlok;
    
    private Point3D huidigePositie;
    private Veld velden[][][];
    private Timer timer;
    private int aantallijnen = 0;
    private boolean pauze = false;
    private int x;
    private int y;
    private int z;

    public Bord(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
        velden = new Veld[x + 2][y + 2][z + 2];
        huidigBlok = BlokFabriek.maakNieuwBlok();
        volgendBlok = BlokFabriek.maakNieuwBlok();
        huidigePositie = new Point3D(5, 1, 1);
        init();
        timer = new Timer(1000, this);
        timer.start();
        
    }

    public void beweegX(int dir) {
        set(dir, 0,0);
        
        this.setChanged();
        this.notifyObservers();
    }

    public void beweegY(int dir) {

        if(!veranderenMogelijk(0, dir, 0)){
            set(0,dir,0);
            this.nieuw();
        }
        else{
            set(0, dir,0);
        }
 
        this.setChanged();
        this.notifyObservers();
    }
    
    public void beweegZ(int dir) {
        set(0, 0, dir);
        
        this.setChanged();
        this.notifyObservers();
    }

    public void toggle() {
        set(0,0,0);

        this.setChanged();
        this.notifyObservers();
    }

    private boolean veranderenMogelijk( int x, int y, int z) {
        
        boolean mogelijk = true;
        AbstractBlok nBlok = huidigBlok.clone();
        
        if(x==0&& y==0 && z==0) nBlok.toggle();
        Point3D nPos = new Point3D(huidigePositie.x + x,
                                    huidigePositie.y + y,
                                    huidigePositie.z + z);
        
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++) 
                if (nBlok.returnBlok()[i][j] == true) 
                    if (velden[nPos.x+i][nPos.y+j][nPos.z].isBezet() ==true) 
                        mogelijk = false;
 
        return mogelijk;
    }

    private void init() {
        for (int i = 0; i < x + 2; i++) {
            for (int j = 0; j < y + 2; j++) {
                for (int k = 0; k < z + 2; k++) {
                    if (i < 1 || i > x || k < 1 || k > z || j > y) {
                        velden[i][j][k] = new Veld(new EnkelBlok(Color.BLACK));
                    } else {
                        velden[i][j][k] = new Veld();
                    }
                }
            }
        }
    }

    public Veld[][][] getBord() {
        
        Veld[][][] tempVelden = new Veld[x][y][z];
        
        for (int i = 1; i <= x; i++)
            for (int j = 1; j <= y; j++)
                for (int k = 1; k <= z; k++)
                    tempVelden[i-1][j-1][k-1] = velden[i][j][k].clone();
        
         for (int i = 0; i < 4; i++) 
                for (int j = 0; j < 4; j++) 
                    if (huidigBlok.returnBlok()[i][j] == true) 
                        tempVelden[huidigePositie.x -1 + i][huidigePositie.y -1  + j][huidigePositie.z -1 ].setBlok(new EnkelBlok(huidigBlok.getKleur()));
        
        return tempVelden;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
    
    public int getZ() {
        return y;
    }

    public void nieuw() {
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++) 
                if (huidigBlok.returnBlok()[i][j] == true)
                    velden[huidigePositie.x + i][huidigePositie.y + j][huidigePositie.z].setBlok(new EnkelBlok(huidigBlok.getKleur()));           
         
        controleerOpLijnen(); 

        huidigBlok = volgendBlok;
        volgendBlok = BlokFabriek.maakNieuwBlok();
        huidigePositie = new Point3D(5, 1, 1);
        
    }

    public void actionPerformed(ActionEvent arg0) {
        beweegY(1);
    }

    private void set(int x, int y, int z) {
        if (veranderenMogelijk(x, y, z)) {     
            if(x==0&& y==0 && z==0) huidigBlok.toggle();
            huidigePositie.x += x;
            huidigePositie.y += y;
            huidigePositie.z += z;
        }
    }
    
    private void controleerOpLijnen(){
        for (int i = 1; i <= y; i++){
            boolean lijnIsVolledig = true;
            for (int j = 1; j <= x ; j++)
                for (int k = 1; k <= z ; k++)
                    if(!velden[j][i][k].isBezet())
                        lijnIsVolledig = false;
                    

            if(lijnIsVolledig)
                verwijderLijn(i);

        }
    }

    public void verwijderLijn(int yy) {

        for (int i = 1; i < x+1; i++) {
            for (int k = 1; k < z+1; k++) {
                for (int j = yy; j > 2; j--) {
                    velden[i][j][k].setBlok(velden[i][j-1][k].getBlok());
                    velden[i][j-1][k].clear();
                }
            }
        }
        
        aantallijnen++;
        this.setChanged();
        this.notifyObservers(1);
 
    }
    
    public AbstractBlok getVolgendBlok(){
        return volgendBlok;
    }

    public int getAantallijnen() {
        return aantallijnen;
    }
    
    public void pauze () {
        if (! pauze){
            timer.stop();
            pauze = true;
        } else {
            timer.start();
            pauze = false;
        }
    }
    
    public void versnelTimer (int delay) {
        timer.stop();
        timer = new Timer (delay,this);
        timer.start();
        System.out.println("in bord > "+timer.getDelay());
    }
    
    
}












